package cn.zmwh.im.server.utils;

import cn.zmwh.im.server.constant.Constants;
import cn.zmwh.im.server.mq.dto.LoginInfo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class JwtUtil implements ApplicationRunner {


    // 静态内部类持有secret
    private static class Holder {
        static String secret;
    }

    @Value("${jwt.secret}")
    private String instanceSecret;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Holder.secret = instanceSecret; // Spring注入后初始化静态字段
    }

    /**
     * 从token中获取JWT中的负载
     */
    public static LoginInfo getInfoFromToken(String token) {
        LoginInfo loginInfo = new LoginInfo();
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(Holder.secret)
                    .parseClaimsJws(token)
                    .getBody();
            Long uid = claims.get(Constants.UID, Long.class);
            String terminal = claims.get(Constants.TERMINAL, String.class);
            if (uid == null) {
                uid = claims.get("dpId", Long.class);
            }
            loginInfo.setId(uid);
            loginInfo.setTerminal(terminal);
            loginInfo.setEffectivity(true);
            loginInfo.setClaims(claims);
            return loginInfo;
        } catch (ExpiredJwtException e) {
            Claims claims = e.getClaims();
            loginInfo.setClaims(claims);
            Long uid = claims.get(Constants.UID, Long.class);
            String terminal = claims.get(Constants.TERMINAL, String.class);
            log.error(uid + "Token失效");
            loginInfo.setId(uid);
            loginInfo.setTerminal(terminal);
            loginInfo.setEffectivity(false);
            loginInfo.setMsg("Token失效");
            return loginInfo;
        } catch (Exception e) {
            log.info("JWT格式验证失败:{}", token, e);
            loginInfo.setEffectivity(false);
            loginInfo.setMsg("JWT格式验证失败");
            return loginInfo;
        }
    }


}
